#include "2440addr.h"


int ReadNandID(void)
{
    int id;

    rNFCONT &= 0xfffffffd;
    rNFCMD   = 0x90;		// readid
    rNFADDR  = 0;

    while( (rNFSTAT&1) ==0) ;  // busy
    id = rNFDATA;
    id = (id<<8 | rNFDATA);
    rNFCONT |= 2;

    return id;
}

int ReadNandStatus(void)
{
    int stat;

    rNFCONT &= 0xfffffffd;
    rNFCMD   = 0x70;		// query
    stat = rNFDATA;
    rNFCONT |= 2;

    return stat;
}

int CheckBadBlk(int page, int flag)
{
    int rv;

    rNFCONT &= 0xfffffffd;
    rNFCMD = 0x50;
    rNFADDR = 5;
    rNFADDR = page&0xe0;
    rNFADDR = ((page>>8)&0xff);
    if(flag) rNFADDR = ((page>>16)&0xff);

    page = 100;
    while(page--) ;

    while( (rNFSTAT&1) ==0) ;  // busy

    rv = rNFDATA;
    if(rv==0xff) rv = 0;
    else rv = 1;

    rNFCMD = 0x00;

    rNFCONT |= 2;

    return rv;

}

void ReadNandPage(int page, char* buf, int flag)
{
    int cnt;


    rNFCONT &= 0xfffffffd;

    rNFCMD   = 0x00;
    rNFADDR = 0;
    rNFADDR = page&0xff;
    rNFADDR = (page>>8)&0xff;
    if(flag) rNFADDR = (page>>16)&0xff;

    rNFCONT |= 0x10;		// init ecc



//    wait_busy

    rNFCMD = 0x70;
    while(rNFDATA&0x40==0);
    rNFCMD = 0;


// end wait busy

    cnt = 512;

    while(cnt--)
    {
        *buf++=rNFDATA;
    }


    rNFCONT |= 2;
}

void nand_boot(char* dst, char* limit)
{
    int id, flag;
    int pagecnt = 0;


    rNFCONF = (7<<12)|(7<<8)|(7<<4);
    rNFCONT = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0);

    id = ReadNandID();

    if(id==0xec73 || id==0xec75)
    {
        flag = 0;
    }
    else
    {
        flag = 1;
    }

    ReadNandStatus();
    while(dst<limit)
    {
        if(pagecnt & 0x1f == 0 )
        {
            while ( CheckBadBlk(pagecnt,flag) )
            {
                pagecnt +=32;
            }
        }
        ReadNandPage(pagecnt, dst, flag);
        dst+=512;
        pagecnt++;
    }
    rNFCONT &= 0xfffffffe;
}

// void copy_proc()